package ltg.ibutton.core.wrappers;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.dalsemi.onewire.OneWireAccessProvider;
import com.dalsemi.onewire.OneWireException;
import com.dalsemi.onewire.adapter.DSPortAdapter;
import com.dalsemi.onewire.adapter.OneWireIOException;
import com.dalsemi.onewire.container.OneWireContainer;

/**
 * @author Francesco Novellis
 *
 */
public class OneWireWinWrapper extends Wrapper {
	
	private DSPortAdapter pdk = null;
	
	private OneWireWinWrapper() {
		try {
			pdk = OneWireAccessProvider.getDefaultAdapter();
		} catch (OneWireIOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (OneWireException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	};
	
	private static final Wrapper INSTANCE = new OneWireWinWrapper();

	public static Wrapper getInstance() {
		return INSTANCE;
	}
	
	public synchronized ArrayList<String> getAll() {
		ArrayList<String> deviceList = new ArrayList<String>();
		try {
			//pdk.beginExclusive(true);
			OneWireContainer owd;
			for(Enumeration<OneWireContainer> owd_enum = pdk.getAllDeviceContainers();
				owd_enum.hasMoreElements();) {
				owd = (OneWireContainer) owd_enum.nextElement();
				deviceList.add(owd.getAddressAsString());
			}
			//pdk.endExclusive();
		} catch (OneWireIOException e) {
			e.printStackTrace();
		} catch (OneWireException e) {
			e.printStackTrace();
		}
		return deviceList;
	}
	
	public synchronized ArrayList<String> getReaders() {
		ArrayList<String> readersList = new ArrayList<String>();
		
		try {
			pdk.beginExclusive(true);
			OneWireContainer owd;
			for(Enumeration<OneWireContainer> owd_enum = pdk.getAllDeviceContainers();
				owd_enum.hasMoreElements();) {
				owd = (OneWireContainer) owd_enum.nextElement();
				Pattern p = Pattern.compile("(81)$");
				Matcher m = p.matcher(owd.getAddressAsString());
				if(m.find())
					readersList.add(owd.getAddressAsString());
			}
			pdk.endExclusive();
		} catch (OneWireIOException e) {
			e.printStackTrace();
		} catch (OneWireException e) {
			e.printStackTrace();
		}
		return readersList;
	}
	
	public synchronized ArrayList<String> getButtons() {
		ArrayList<String> buttonsList = new ArrayList<String>();
		try {
			pdk.beginExclusive(true);
			OneWireContainer owd;
			for(Enumeration<OneWireContainer> owd_enum = pdk.getAllDeviceContainers();
				owd_enum.hasMoreElements();) {
				owd = (OneWireContainer) owd_enum.nextElement();
				Pattern p = Pattern.compile("(01)$");
				Matcher m = p.matcher(owd.getAddressAsString());
				if(m.find())
					buttonsList.add(pdk.getAddressAsString());
			}
			pdk.endExclusive();
		} catch (OneWireIOException e) {
			e.printStackTrace();
		} catch (OneWireException e) {
			e.printStackTrace();
		}
		return buttonsList;
	}
	
	public synchronized ArrayList<String> getButtonsFromPort(String portName) {
		ArrayList<String> buttonsList = new ArrayList<String>();
		try {
			pdk.beginExclusive(true);
			//if (Integer.parseInt(portName.substring(3)) > 0 && pdk.selectPort(portName) && pdk.adapterDetected()) {
				pdk.findFirstDevice();
				Pattern p = Pattern.compile("(01)$");
				Matcher m;
				do {
					m = p.matcher(pdk.getAddressAsString());
					if (m.find())
						buttonsList.add(pdk.getAddressAsString());
				} while (pdk.findNextDevice());
			//}
			pdk.endExclusive();
		} catch (OneWireIOException e) {
			e.printStackTrace();
		} catch (OneWireException e) {
			e.printStackTrace();
		}
		return buttonsList;
	}
}
